<template>
  <div class="api-debugger">
    <div class="debugger-container">
      <div class="debugger-header">
        <div class="header-content">
          <div class="header-icon">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
              <path d="M18 9v3m0 0v3m0-3h3m-3 0h-3M6 9v6a3 3 0 003 3h6a3 3 0 003-3V9a3 3 0 00-3-3H9a3 3 0 00-3 3z" stroke="#67C23A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
            </svg>
          </div>
          <div class="header-text">
            <h2 class="debugger-title">接口调试器</h2>
            <p class="debugger-subtitle">测试接口并查看响应结果</p>
          </div>
        </div>
        <div class="header-tag">
          <el-tag 
            :type="debugMode === 'mock' ? 'success' : 'warning'" 
            size="small"
            effect="dark"
          >
            {{ debugMode === 'mock' ? 'Mock模式' : '真实接口' }}
          </el-tag>
        </div>
      </div>
      
      <div class="debugger-content">
        <!-- 调试控制栏 -->
        <div class="debug-controls">
          <div class="request-info">
            <el-tag 
              :type="getMethodTagType(debugForm.method)" 
              size="small"
              effect="dark"
            >
              {{ debugForm.method }}
            </el-tag>
            <div class="url-display">
              <span class="url-prefix">/api</span>
              <span class="url-path">{{ debugForm.url }}</span>
            </div>
          </div>
          
          <div class="control-actions">
            <el-button 
              type="primary" 
              @click="sendRequest"
              :loading="loading"
              round
              class="send-btn"
            >
              <el-icon><Promotion /></el-icon>
              {{ loading ? '发送中...' : '发送请求' }}
            </el-button>
          </div>
        </div>
        
        <!-- 模式切换 -->
        <div class="mode-switch">
          <el-radio-group 
            v-model="debugMode" 
            size="small"
            @change="onModeChange"
          >
            <el-radio-button label="mock" class="mode-option">
              <el-icon><MagicStick /></el-icon>
              Mock模式
            </el-radio-button>
            <el-radio-button label="real" class="mode-option">
              <el-icon><Connection /></el-icon>
              真实接口
            </el-radio-button>
          </el-radio-group>
        </div>
        
        <!-- 内容区域 -->
        <div class="content-sections">
          <!-- 参数部分 -->
          <div class="section">
            <div class="section-header">
              <h3 class="section-title">
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" class="section-icon">
                  <path d="M4 6h16M4 12h16M4 18h16" stroke="#67C23A" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
                请求参数
              </h3>
            </div>
            
            <div class="params-container" v-if="Object.keys(mockParams).length > 0">
              <el-row :gutter="16">
                <el-col 
                  :span="12" 
                  v-for="(value, key) in mockParams" 
                  :key="key"
                  class="param-col"
                >
                  <div class="param-item">
                    <label class="param-label">{{ key }}</label>
                    <el-input 
                      v-model="requestParams[key]" 
                      :placeholder="key"
                      size="small"
                      class="param-input"
                    ></el-input>
                  </div>
                </el-col>
              </el-row>
            </div>
            
            <div class="empty-state" v-else>
              <div class="empty-icon">
                <svg width="48" height="48" viewBox="0 0 24 24" fill="none">
                  <path d="M12 8v4M12 16h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" stroke="#C0C4CC" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
              </div>
              <p class="empty-text">当前接口无参数</p>
            </div>
          </div>
          
          <!-- 响应部分 -->
          <div class="section">
            <div class="section-header">
              <h3 class="section-title">
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" class="section-icon">
                  <path d="M5 12h14M12 5l7 7-7 7" stroke="#E6A23C" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
                响应结果
              </h3>
              <div class="response-actions">
                <el-button 
                  size="small" 
                  @click="copyResponse"
                  :disabled="!rawResponse"
                  round
                  class="action-btn"
                >
                  <el-icon><CopyDocument /></el-icon>
                  复制
                </el-button>
                <el-button 
                  size="small" 
                  @click="clearResponse"
                  :disabled="!rawResponse"
                  round
                  class="action-btn"
                >
                  <el-icon><Delete /></el-icon>
                  清空
                </el-button>
              </div>
            </div>
            
            <div class="response-container" v-if="rawResponse || responseStatus">
              <div class="response-header">
                <div class="response-info">
                  <el-tag 
                    v-if="responseStatus" 
                    :type="getResponseStatusType(responseStatus)"
                    size="small"
                    effect="dark"
                  >
                    {{ responseStatus }}
                  </el-tag>
                  <span class="response-time" v-if="responseTime">
                    耗时: {{ responseTime }}ms
                  </span>
                </div>
              </div>
              
              <div class="response-content">
                <pre class="response-data">{{ formattedResponse }}</pre>
              </div>
            </div>
            
            <div class="empty-state" v-else>
              <div class="empty-icon">
                <svg width="48" height="48" viewBox="0 0 24 24" fill="none">
                  <path d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" stroke="#C0C4CC" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  <path d="M9 10h.01M15 10h.01M12 12v4" stroke="#C0C4CC" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                </svg>
              </div>
              <p class="empty-text">发送请求以查看响应结果</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, reactive, computed, watch } from 'vue'
import axios from 'axios'
import { 
  Promotion,
  MagicStick, 
  Connection,
  CopyDocument,
  Delete
} from '@element-plus/icons-vue'
import { generateMockData, generateMockParams } from '../utils/mockGenerator'

export default {
  name: 'ApiDebugger',
  components: {
    Promotion,
    MagicStick,
    Connection,
    CopyDocument,
    Delete
  },
  props: {
    apiDoc: {
      type: Object,
      required: true
    }
  },
  setup(props) {
    // 加载状态
    const loading = ref(false)
    
    // 调试表单
    const debugForm = reactive({
      method: computed(() => props.apiDoc.method),
      url: computed(() => props.apiDoc.url)
    })
    
    // 调试模式
    const debugMode = ref('mock')
    
    // Mock参数
    const mockParams = computed(() => {
      return generateMockParams(props.apiDoc)
    })
    
    // 请求参数
    const requestParams = reactive({...mockParams.value})
    
    // 响应数据
    const rawResponse = ref('')
    const responseStatus = ref('')
    const responseTime = ref(0)
    
    const formattedResponse = computed(() => {
      try {
        if (!rawResponse.value) return ''
        return JSON.stringify(JSON.parse(rawResponse.value), null, 2)
      } catch (e) {
        return rawResponse.value
      }
    })
    
    // 获取请求方式对应的标签类型
    const getMethodTagType = (method) => {
      switch(method) {
        case 'GET': return 'primary'
        case 'POST': return 'success'
        case 'PUT': return 'warning'
        case 'DELETE': return 'danger'
        default: return 'info'
      }
    }
    
    // 获取响应状态类型
    const getResponseStatusType = (status) => {
      if (!status) return 'info'
      if (typeof status === 'string' && status.includes('Mock')) return 'success'
      if (typeof status === 'string' && status === 'Error') return 'danger'
      if (status >= 200 && status < 300) return 'success'
      if (status >= 400 && status < 500) return 'warning'
      if (status >= 500) return 'danger'
      return 'info'
    }
    
    // 监听Mock参数变化，更新请求参数
    watch(mockParams, (newParams) => {
      Object.keys(newParams).forEach(key => {
        requestParams[key] = newParams[key]
      })
    })
    
    // 模式切换处理
    const onModeChange = () => {
      // 模式切换时可以添加其他逻辑
    }
    
    // 清空响应
    const clearResponse = () => {
      rawResponse.value = ''
      responseStatus.value = ''
      responseTime.value = 0
    }
    
    // 复制响应
    const copyResponse = async () => {
      try {
        await navigator.clipboard.writeText(rawResponse.value)
        // 可以添加成功提示
      } catch (err) {
        // 复制失败处理
      }
    }
    
    // 发送请求
    const sendRequest = async () => {
      if (loading.value) return
      
      loading.value = true
      clearResponse()
      
      const startTime = Date.now()
      
      try {
        if (debugMode.value === 'mock') {
          // Mock模式
          await new Promise(resolve => setTimeout(resolve, 500)) // 模拟网络延迟
          const mockData = generateMockData(props.apiDoc)
          rawResponse.value = JSON.stringify(mockData, null, 2)
          responseStatus.value = '200 OK (Mock)'
          responseTime.value = Date.now() - startTime
        } else {
          // 真实接口模式
          const params = {}
          Object.keys(requestParams).forEach(key => {
            params[key] = requestParams[key]
          })
          
          const config = {
            method: debugForm.method,
            url: `/api${debugForm.url}`
          }
          
          if (debugForm.method === 'GET') {
            config.params = params
          } else {
            config.data = params
          }
          
          const response = await axios(config)
          rawResponse.value = JSON.stringify(response.data, null, 2)
          responseStatus.value = `${response.status} ${response.statusText}`
          responseTime.value = Date.now() - startTime
        }
      } catch (error) {
        responseTime.value = Date.now() - startTime
        if (axios.isAxiosError(error)) {
          if (error.response) {
            rawResponse.value = JSON.stringify(error.response.data, null, 2)
            responseStatus.value = `${error.response.status} ${error.response.statusText}`
          } else {
            rawResponse.value = `请求出错: ${error.message}`
            responseStatus.value = 'Error'
          }
        } else {
          rawResponse.value = `请求出错: ${error.message}`
          responseStatus.value = 'Error'
        }
      } finally {
        loading.value = false
      }
    }
    
    return {
      loading,
      debugForm,
      debugMode,
      mockParams,
      requestParams,
      rawResponse,
      responseStatus,
      responseTime,
      formattedResponse,
      getMethodTagType,
      getResponseStatusType,
      onModeChange,
      sendRequest,
      clearResponse,
      copyResponse
    }
  }
}
</script>

<style scoped>
.api-debugger {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.debugger-container {
  background: white;
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  border: 1px solid #ebeef5;
}

.debugger-header {
  background: #f5f7fa;
  padding: 16px 20px;
  border-bottom: 1px solid #ebeef5;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-content {
  display: flex;
  align-items: center;
  gap: 12px;
}

.header-icon {
  background: #f0f9eb;
  border-radius: 10px;
  padding: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.debugger-title {
  font-size: 18px;
  font-weight: 600;
  margin: 0 0 2px 0;
  color: #303133;
}

.debugger-subtitle {
  font-size: 12px;
  margin: 0;
  color: #909399;
}

.debugger-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.debug-controls {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  background: #fafafa;
  border-bottom: 1px solid #ebeef5;
  gap: 16px;
}

.request-info {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
}

.url-display {
  display: flex;
  align-items: center;
  background: white;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 6px 12px;
  flex: 1;
  max-width: 300px;
  overflow: hidden;
}

.url-prefix {
  color: #909399;
  font-size: 14px;
  margin-right: 4px;
  flex-shrink: 0;
}

.url-path {
  font-size: 14px;
  color: #303133;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.control-actions {
  flex-shrink: 0;
}

.send-btn {
  transition: all 0.3s ease;
}

.send-btn:hover:not(.is-disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
}

.mode-switch {
  padding: 16px 20px;
  border-bottom: 1px solid #ebeef5;
  background: #fafafa;
}

.mode-switch :deep(.el-radio-group) {
  display: flex;
}

.mode-option :deep(.el-radio-button__inner) {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  transition: all 0.3s ease;
}

.mode-option :deep(.el-radio-button__inner):hover {
  transform: translateY(-1px);
}

.content-sections {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
}

.section {
  margin-bottom: 24px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.section-title {
  font-size: 16px;
  font-weight: 600;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  color: #303133;
}

.section-icon {
  flex-shrink: 0;
}

.response-actions {
  display: flex;
  gap: 8px;
}

.action-btn {
  transition: all 0.3s ease;
}

.action-btn:hover:not(.is-disabled) {
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.params-container {
  background: white;
  border-radius: 8px;
  border: 1px solid #ebeef5;
  padding: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.param-col {
  margin-bottom: 16px;
}

.param-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.param-label {
  font-size: 13px;
  color: #606266;
  font-weight: 500;
}

.param-input :deep(.el-input__inner) {
  border-radius: 4px;
  transition: all 0.3s ease;
}

.param-input :deep(.el-input__inner):focus {
  box-shadow: 0 0 0 1px #409EFF inset;
}

.response-container {
  background: white;
  border-radius: 8px;
  border: 1px solid #ebeef5;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.response-header {
  padding: 12px 16px;
  border-bottom: 1px solid #ebeef5;
  background: #fafafa;
}

.response-info {
  display: flex;
  align-items: center;
  gap: 12px;
}

.response-time {
  font-size: 12px;
  color: #909399;
}

.response-content {
  max-height: 300px;
  overflow-y: auto;
}

.response-data {
  margin: 0;
  padding: 16px;
  background: #2d2d2d;
  color: #f8f8f2;
  font-family: 'Consolas', 'Courier New', monospace;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-wrap: break-word;
}

.empty-state {
  text-align: center;
  padding: 40px 20px;
  background: white;
  border-radius: 8px;
  border: 1px dashed #ebeef5;
}

.empty-icon {
  margin-bottom: 16px;
}

.empty-text {
  color: #909399;
  font-size: 14px;
  margin: 0;
}
</style>